<template>
	<div class="attribute-selector-view">
		<!-- 滚动容器 -->
		<div v-loading="loading" class="scroll-container">
			<!-- 已选择的属性展示 - 固定在顶部 -->
			<div class="selected-attributes-display">
				<div class="selected-info">
					<el-text class="selected-label">已选规格：</el-text>
					<el-text :type="Object.keys(selectedAttributes).length > 0 ? 'primary' : 'info'">
						{{ selectedAttributesText }}
					</el-text>
				</div>
				<el-button v-auth="'/api/SysMaterialAttribute/Add'" type="primary" size="small" class="add-attribute-btn" @click="onAddAttribute">
					<el-icon><Plus /></el-icon>
					<span>添加属性</span>
				</el-button>
			</div>

			<!-- 属性选择器内容 -->
			<div class="attributes-container">
				<template v-if="filteredAttributeList.length === 0 && !loading">
					<el-empty description="该物料暂无属性数据" />
				</template>

				<template v-else>
					<div v-for="attr in filteredAttributeList" :key="attr.ID" class="attribute-group">
						<div class="attribute-name" :class="{ 'is-key': attr.IsKeyAttribute ?? attr.isKeyAttribute }">
							<el-text class="attr-label">
								<i v-if="attr.IsKeyAttribute ?? attr.isKeyAttribute" class="el-icon-star-on key-icon"></i>
								{{ attr.Name }}
							</el-text>
							<el-button v-auth="'/api/SysMaterialAttribute/Edit'" link size="small" type="primary" class="attr-edit" @click="onAttribute(attr)">
								<el-icon><Edit /></el-icon>
								<span>编辑</span>
							</el-button>
						</div>
						<div class="attribute-values">
							<div
								v-for="(valueItem, index) in attr.Values"
								:key="attr.ID + '-' + index"
								:class="[
									'attribute-value-item',
									{ 'is-selected': selectedAttributes[attr.Name || ''] === valueItem.Value },
									{ 'is-key-attribute': attr.IsKeyAttribute ?? attr.isKeyAttribute },
									{ 'is-disabled': !isPurchaseScenario && (valueItem.InStock === 0 || valueItem.InStock === null) },
								]"
								@click="handleValueClick(attr, valueItem)"
							>
								<span class="value-text">{{ valueItem.Value }}</span>
								<span class="stock-text">库存：{{ valueItem.InStock ?? 0 }}</span>
								<i v-if="selectedAttributes[attr.Name || ''] === valueItem.Value" class="check-icon el-icon-check"></i>
							</div>
						</div>
					</div>
				</template>
			</div>
		</div>
	</div>
</template>

<script setup lang="ts">
import { ref, reactive, computed, watch, defineAsyncComponent } from 'vue';
import { ElMessage } from 'element-plus';
import { Edit, Plus } from '@element-plus/icons-vue';
import type { ISysMaterialAttributeView } from './types';
import type { ISysMaterialVm, ISysMaterial } from '/@/views/supplychain/sysmaterial/api/interface';
import { SysMaterialApi } from '/@/views/supplychain/sysmaterial/api';
import other from '/@/utils/other';

const EditDialog = defineAsyncComponent(() => import('/@/views/supplychain/sysmaterialattribute/edit.vue'));
const CreateDialog = defineAsyncComponent(() => import('/@/views/supplychain/sysmaterialattribute/create.vue'));

/**
 * ==================== Props & Emits ====================
 */
interface Props {
	/** 物料数据（可以是 ViewModel 或 Entity） */
	material: ISysMaterialVm | ISysMaterial | null;
	/** 是否为采购场景（true: 显示所有属性；false: 仅显示关键属性） */
	isPurchaseScenario?: boolean;
	/** 默认选中的属性值 ID 数组（用于回显） */
	defaultAttributeValueIds?: string[];
}

interface Emits {
	/**
	 * 属性选择变化事件
	 * @param attributeIds - 属性值 ID 映射 { 属性名: 属性值ID }
	 * @param attributeValues - 属性值映射 { 属性名: 属性值 }
	 * @param isRestoring - 是否为回显操作（true: 回显，false: 用户选择）
	 */
	(e: 'change', attributeIds: Record<string, string>, attributeValues: Record<string, string>, isRestoring?: boolean): void;
}

const props = withDefaults(defineProps<Props>(), {
	isPurchaseScenario: false,
});
const emit = defineEmits<Emits>();

/**
 * ==================== API & 数据状态 ====================
 */
const materialApi = SysMaterialApi(); // 物料 API 实例

// 属性列表（从物料数据中加载）
const attributeList = ref<ISysMaterialAttributeView[]>([]);
// 已选属性值映射 { 属性名: 属性值 }
const selectedAttributes = ref<Record<string, string>>({});
// 已选属性值 ID 映射 { 属性名: 属性值ID }
const selectedAttributeIds = ref<Record<string, string>>({});
// 加载状态
const loading = ref(false);

/**
 * ==================== 计算属性 ====================
 */
/**
 * 过滤后的属性列表
 * @description 根据场景决定显示哪些属性
 * - 采购场景：显示所有属性（关键属性 + 非关键属性）
 * - 非采购场景：仅显示关键属性
 */
const filteredAttributeList = computed(() => {
	if (props.isPurchaseScenario) {
		return attributeList.value; // 显示全部
	} else {
		return attributeList.value.filter((attr) => attr.IsKeyAttribute); // 仅关键属性
	}
});

/**
 * 已选属性文本（用于界面展示）
 * @description 按照属性原始顺序展示，格式：颜色: 红色 / 尺寸: XL
 * @note 使用完整的 attributeList 而不是 filteredAttributeList，以包含所有已选属性（包括非关键属性）
 */
const selectedAttributesText = computed(() => {
	const selectedKeys = Object.keys(selectedAttributes.value);
	if (selectedKeys.length === 0) return '未选择';

	// 按照 attributeList 中的顺序排序（包含所有属性，不仅仅是关键属性）
	const orderedSelectedAttrs = attributeList.value
		.filter((attr) => selectedAttributes.value[attr.Name || ''])
		.map((attr) => `${attr.Name}: ${selectedAttributes.value[attr.Name || '']}`);

	return orderedSelectedAttrs.join(' / ');
});

/**
 * 属性值 ID 数组（按属性顺序）
 * @description 用于提交给后端创建/获取 SKU
 * @note 使用完整的 attributeList 而不是 filteredAttributeList，以包含所有已选属性（包括非关键属性）
 */
const attributeValueIds = computed(() => {
	return attributeList.value
		.filter((attr) => selectedAttributeIds.value[attr.Name || ''])
		.map((attr) => selectedAttributeIds.value[attr.Name || ''])
		.filter((id) => id && id.trim() !== ''); // 过滤空值
});

/**
 * ==================== 数据加载 ====================
 */
/**
 * 加载物料属性
 * @description 根据物料 ID 获取完整的属性数据（包括属性值和库存）
 */
const loadAttributes = async (): Promise<void> => {
	// 提取物料 ID（兼容 ViewModel 和 Entity 两种格式）
	const materialId = (props.material as ISysMaterialVm)?.Entity?.MaterialId || (props.material as ISysMaterial)?.ID;

	if (!materialId) {
		attributeList.value = [];
		return;
	}

	try {
		loading.value = true;

		// 调用 Get 接口获取完整物料数据
		const materialData: any = await materialApi.get(materialId);
		const materialEntity = materialData.Entity;
		const attributeData = materialEntity.Attributes || [];

		// 转换为标准属性格式
		attributeList.value = attributeData.map((attr: any) => ({
			ID: attr.ID,
			Name: attr.Name,
			MaterialName: attr.MaterialName,
			// 兼容后端字段大小写不一致问题
			IsKeyAttribute: attr.IsKeyAttribute ?? attr.isKeyAttribute ?? false,
			MaterialId: attr.MaterialId || null,
			Remark: attr.Remark || null,
			Order: attr.Order || null,
			InStock: attr.InStock || null,
			Values: Array.isArray(attr.Values) ? attr.Values : [],
		}));

		// 如果有默认值，自动回显
		if (props.defaultAttributeValueIds && props.defaultAttributeValueIds.length > 0) {
			restoreDefaultSelection();
		}
	} catch (error) {
		console.error('加载物料属性失败:', error);
		ElMessage.error('加载物料属性失败');
		attributeList.value = [];
	} finally {
		loading.value = false;
	}
};

/**
 * ==================== 属性选择与回显 ====================
 */
/**
 * 根据默认属性值 ID 恢复选中状态（用于回显）
 * @description 遍历属性列表，找到对应的属性值并选中
 */
const restoreDefaultSelection = (): void => {
	if (!props.defaultAttributeValueIds || props.defaultAttributeValueIds.length === 0) {
		return;
	}

	// 清空当前选择
	clearSelection();

	// 遍历属性值 ID，在属性列表中查找并选中
	props.defaultAttributeValueIds.forEach((valueId: string) => {
		for (const attr of attributeList.value) {
			const attrValues = (attr as any).Values;
			if (attrValues) {
				const foundValue = attrValues.find((v: any) => v.ID === valueId);
				if (foundValue && attr.Name) {
					selectedAttributeIds.value[attr.Name] = valueId;
					selectedAttributes.value[attr.Name] = foundValue.Value;
					break; // 找到后跳出内层循环
				}
			}
		}
	});

	// 触发 change 事件（第三个参数 true 表示这是回显操作）
	emit('change', { ...selectedAttributeIds.value }, { ...selectedAttributes.value }, true);
};

/**
 * 清空选择状态
 */
const clearSelection = (): void => {
	Object.keys(selectedAttributes.value).forEach((key) => {
		delete selectedAttributes.value[key];
	});
	Object.keys(selectedAttributeIds.value).forEach((key) => {
		delete selectedAttributeIds.value[key];
	});
};

/**
 * ==================== 事件处理 ====================
 */
/**
 * 打开属性添加弹窗
 */
const onAddAttribute = (): void => {
	// 获取物料 ID
	const materialId = (props.material as ISysMaterialVm)?.Entity?.MaterialId || (props.material as ISysMaterial)?.ID;
	if (!materialId) {
		ElMessage.warning('物料ID不存在，无法添加属性');
		return;
	}
	// 使用 other.openDialog 打开创建弹窗
	other.openDialog('添加属性', CreateDialog, { MaterialId: materialId }, () => {
		// 弹窗关闭后重新加载属性数据
		loadAttributes();
	});
};

/**
 * 打开属性编辑弹窗
 * @param attr - 属性对象
 */
const onAttribute = (attr: ISysMaterialAttributeView): void => {
	if (!attr.ID) {
		console.warn('AttributeSelector: 属性ID不存在，无法打开编辑弹窗');
		ElMessage.warning('属性ID不存在，无法打开编辑弹窗');
		return;
	}
	// 使用 other.openDialog 打开编辑弹窗
	other.openDialog('修改属性', EditDialog, { ID: attr.ID }, () => {
		// 弹窗关闭后重新加载属性数据
		const materialId = (props.material as ISysMaterialVm)?.Entity?.MaterialId || (props.material as ISysMaterial)?.ID;
		if (materialId) {
			loadAttributes();
		}
	});
};

/**
 * 处理属性值点击（模板调用）
 */
const handleValueClick = (attr: any, valueItem: any): void => {
	const attrName = attr.Name || '';
	const attrValue = valueItem.Value || '';
	const attrValueId = valueItem.ID || '';
	const inStock = valueItem.InStock;

	// 库存检查（仅非采购场景）
	if (!props.isPurchaseScenario && (inStock === 0 || inStock === null)) {
		ElMessage.warning('该规格库存不足，无法选择');
		return;
	}

	toggleAttributeValue(attrName, attrValue, attrValueId);
};

/**
 * 切换属性值选择状态
 * @param attrName - 属性名称
 * @param attrValue - 属性值
 * @param attrValueId - 属性值 ID
 */
const toggleAttributeValue = (attrName: string, attrValue: string, attrValueId: string): void => {
	// 验证属性值 ID
	if (!attrValueId || attrValueId.trim() === '') {
		console.error('[AttributeSelector] 属性值ID无效', { attrName, attrValue, attrValueId });
		ElMessage.error('属性值ID无效，请联系管理员');
		return;
	}

	// 切换选择状态
	if (selectedAttributes.value[attrName] === attrValue) {
		// 已选中，执行取消
		delete selectedAttributes.value[attrName];
		delete selectedAttributeIds.value[attrName];
	} else {
		// 未选中，执行选中（单选模式：会覆盖该属性的旧值）
		selectedAttributes.value[attrName] = attrValue;
		selectedAttributeIds.value[attrName] = attrValueId;
	}

	// 触发 change 事件（第三个参数 false 表示用户主动选择）
	emit('change', { ...selectedAttributeIds.value }, { ...selectedAttributes.value });
};

/**
 * ==================== 监听器 ====================
 */
/**
 * 监听物料变化
 * @description 物料变化时，重新加载属性并清空选择状态
 */
watch(
	() => props.material,
	(newMaterial) => {
		if (newMaterial) {
			clearSelection(); // 清空旧的选择状态
			loadAttributes(); // 加载新物料的属性
		} else {
			attributeList.value = [];
			clearSelection();
		}
	},
	{ immediate: true }
);

/**
 * 监听默认属性值 ID 变化
 * @description 用于回显选中状态（例如：编辑模式）
 */
watch(
	() => props.defaultAttributeValueIds,
	(newIds) => {
		// 只有当属性列表已加载且有默认值时，才恢复选中状态
		if (newIds && newIds.length > 0 && attributeList.value.length > 0) {
			restoreDefaultSelection();
		}
	},
	{ deep: true }
);

/**
 * ==================== 对外暴露 ====================
 */
defineExpose({
	selectedAttributes, // 已选属性值映射
	selectedAttributeIds, // 已选属性值 ID 映射
	selectedAttributesText, // 已选属性文本
	attributeValueIds, // 属性值 ID 数组（按顺序）
	attributeList, // 属性列表（供父组件判断关键属性）
});
</script>

<style scoped lang="scss">
.attribute-selector-view {
	height: 100%;
	overflow: hidden;
	padding: 0;

	.scroll-container {
		height: 100%;
		overflow-y: auto;
		overflow-x: hidden;

		// 自定义滚动条样式
		&::-webkit-scrollbar {
			width: 4px;
			height: 4px;
		}

		&::-webkit-scrollbar-track {
			background: var(--el-fill-color-lighter);
			border-radius: 2px;
			margin: 2px 0;
		}

		&::-webkit-scrollbar-thumb {
			background: var(--el-border-color);
			border-radius: 2px;
			transition: background 0.2s;

			&:hover {
				background: var(--el-border-color-hover);
			}

			&:active {
				background: var(--el-text-color-placeholder);
			}
		}
	}

	.selected-attributes-display {
		position: sticky;
		top: 0;
		z-index: 10;
		padding: 6px 10px;
		margin: 8px 10px 8px;
		background: rgba(255, 255, 255, 0.95);
		background: linear-gradient(135deg, rgba(236, 245, 255, 0.98) 0%, rgba(230, 244, 255, 0.98) 100%);
		border: 1px solid var(--el-color-primary-light-6);
		border-radius: 4px;
		display: flex;
		align-items: center;
		justify-content: space-between;
		gap: 8px;
		box-shadow: 0 1px 4px rgba(64, 158, 255, 0.1);
		transition: all 0.3s;
		backdrop-filter: blur(10px);

		&:hover {
			box-shadow: 0 2px 6px rgba(64, 158, 255, 0.15);
		}

		.selected-info {
			display: flex;
			align-items: center;
			gap: 6px;
			flex: 1;
			min-width: 0;
		}

		.selected-label {
			font-weight: 600;
			font-size: 12px;
			color: var(--el-color-primary);
			flex-shrink: 0;
		}

		:deep(.el-text) {
			font-size: 12px;
			line-height: 1.4;
		}

		.add-attribute-btn {
			flex-shrink: 0;
			height: 24px;
			padding: 0 10px;
			font-size: 12px;
			display: inline-flex;
			align-items: center;
			gap: 4px;

			:deep(.el-icon) {
				font-size: 14px;
			}
		}
	}

	.attributes-container {
		padding: 0 10px 10px;
		.attribute-group {
			margin-bottom: 8px;
			padding: 6px 8px;
			background: var(--el-fill-color-blank);
			border-radius: 4px;
			border: 1px solid var(--el-border-color-lighter);
			transition: all 0.2s;

			&:hover {
				border-color: var(--el-border-color-light);

				.attribute-name .attr-edit {
					opacity: 1;
				}
			}

			&:last-child {
				margin-bottom: 0;
			}

			.attribute-name {
				margin-bottom: 6px;
				padding-bottom: 4px;
				border-bottom: 1px solid var(--el-border-color-lighter);
				display: flex;
				align-items: center;
				justify-content: space-between;

				&.is-key {
					.attr-label {
						color: var(--el-color-warning-dark-2);

						&::before {
							background: var(--el-color-warning);
						}
					}

					.key-icon {
						color: var(--el-color-warning);
						margin-right: 4px;
						font-size: 13px;
						vertical-align: middle;
					}
				}

				.attr-label {
					font-size: 12px;
					font-weight: 600;
					color: var(--el-text-color-primary);
					position: relative;
					padding-left: 6px;

					&::before {
						content: '';
						position: absolute;
						left: 0;
						top: 50%;
						transform: translateY(-50%);
						width: 2px;
						height: 10px;
						background: var(--el-color-primary);
						border-radius: 1px;
					}

					&::after {
						content: ':';
						margin-left: 2px;
					}
				}

				.attr-edit {
					font-size: 11px;
					padding: 2px 6px;
					height: 20px;
					opacity: 0;
					transition: all 0.3s ease;
					display: inline-flex;
					align-items: center;

					:deep(.el-icon) {
						font-size: 12px;
						margin-right: 2px;
					}

					&:hover {
						transform: translateX(-2px);
						background: var(--el-color-primary-light-9);
						border-radius: 3px;
					}
				}
			}

			.attribute-values {
				display: flex;
				flex-wrap: wrap;
				gap: 6px;

				.attribute-value-item {
					position: relative;
					padding: 3px 10px;
					border: 1px solid var(--el-border-color);
					border-radius: 4px;
					background: var(--el-fill-color-blank);
					cursor: pointer;
					transition: all 0.2s;
					user-select: none;
					min-height: 24px;
					display: inline-flex;
					align-items: center;
					gap: 4px;
					font-size: 12px;
					color: var(--el-text-color-regular);

					&:hover {
						border-color: var(--el-color-primary);
						color: var(--el-color-primary);
						background: var(--el-color-primary-light-9);
					}

					&.is-selected {
						border-color: var(--el-color-primary);
						background: linear-gradient(135deg, var(--el-color-primary) 0%, var(--el-color-primary-light-3) 100%);
						color: var(--el-color-white);
						font-weight: 500;

						&:hover {
							opacity: 0.9;
						}
					}

					&.is-key-attribute {
						border-width: 1px;
						font-weight: 500;

						&:not(.is-selected) {
							border-color: var(--el-color-warning-light-5);
							background: var(--el-color-warning-light-9);

							&:hover {
								border-color: var(--el-color-warning);
								background: var(--el-color-warning-light-8);
							}
						}
					}

					&.is-disabled {
						opacity: 0.5;
						cursor: not-allowed;
						background: var(--el-fill-color-light);
						color: var(--el-text-color-disabled);
						border-color: var(--el-border-color-lighter);

						&:hover {
							border-color: var(--el-border-color-lighter);
							color: var(--el-text-color-disabled);
							background: var(--el-fill-color-light);
						}

						.stock-text {
							color: var(--el-color-danger);
							font-weight: 500;
						}
					}

					.value-text {
						font-size: 12px;
						line-height: 1.2;
					}

					.stock-text {
						font-size: 11px;
						line-height: 1.2;
						color: var(--el-text-color-secondary);
					}

					.check-icon {
						margin-left: 4px;
						font-size: 12px;
					}
				}
			}
		}
	}
}

@keyframes checkIn {
	0% {
		opacity: 0;
		transform: scale(0.5);
	}
	50% {
		transform: scale(1.1);
	}
	100% {
		opacity: 1;
		transform: scale(1);
	}
}
</style>
